JDK1.8源码解析——java.util.concurrent.atomic (1)

本文简单介绍java.util.concurrent.atomic下的:AtomicInteger,AtomicIntegerArray,AtomicIntegerFieldUpdater

Atomic的含义

Atomic意为“原子”,和事务的原子性(atomicity)相似,我们知道事务原子性的含义是在一个事务执行过程中,要么全部完成,要么全部不完成。而JAVA的atomic包原子性的含义是面向多线程的,因此我们可以先这样理解:Atomic操作的变量,要么所有线程都能取到最新状态(值),要么所有线程都取不到。

java.util.concurrent.atomic按数据类型分类有:Boolean、Integer、Long以及泛型,本文只选择Integer进行分析,其他类似。

AtomicInteger

AtomicInteger继承抽象类Number,Number主要用于实现基本数据类型转换,其代码如下:

1
2
3
4
5
6
7
8
public abstract class Number implements java.io.Serializable {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
public byte byteValue() {return (byte)intValue();}
public short shortValue() {return (short)intValue();}
}

AtomicInteger原子操作的关键点在于volatile,而其与JVM线程同步机制有关,这里不做详细介绍(volatile 介绍可参考:https://www.ibm.com/developerworks/cn/java/j-jtp06197.html),简单概括就是使用volatile关键词能保证多线程在访问相同变量时取到的是最新的值,而不是线程独享内存中缓存的变量副本,保证了线程安全。

AtomicInteger中,一些特殊的set操作都是通过sun.misc.Unsafe类完成的,Unsafe类调用的均是本地接口(native),这里不做深入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class AtomicInteger {
private volatile int value;
/**
* 赋值,其他线程立即可见.
*/
public final void set(int newValue) {
value = newValue;
}
/**
* 延迟赋值,其他线程延迟可见.
* 实现非堵塞的写入,无指令重排过程,性能优于set方法
*/
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}
/**
* 对比赋值,其他线程立即可见.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
* JDK1.8:与compareAndSet实现相同.
* JDK1.9:延迟对比赋值,其他线程延迟可见.无指令重排过程,性能优于compareAndSet方法
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
}

AtomicIntegerArray

AtomicIntegerArray为原子整型数组,与AtomicInteger不同的是,其定义的数组是final类型,而且并没有直接将数组设为volatile,因此可以理解为数组大小不可改变,数组内的元素所在内存地址不变,只是允许元素值允许改变。数组元素操作方法与AtomicInteger类相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class AtomicIntegerArray {
private final int[] array;
// 构造函数1——指导大小
public AtomicIntegerArray(int length) {
array = new int[length];
}
// 构造函数2——从已有数组进行克隆
public AtomicIntegerArray(int[] array) {
this.array = array.clone();
}
// 赋值——其他线程立即可见
public final void set(int i, int newValue) {
unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
}
// 延迟赋值,其他线程延迟可见.
public final void lazySet(int i, int newValue) {
unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
}
// 对比赋值,其他线程立即可见.
public final boolean compareAndSet(int i, int expect, int update) {
return compareAndSetRaw(checkedByteOffset(i), expect, update);
}
// JDK1.8与compareAndSet实现相同。JDK1.9:延迟对比赋值,其他线程延迟可见
public final boolean weakCompareAndSet(int i, int expect, int update) {
return compareAndSet(i, expect, update);
}
}

AtomicIntegerFieldUpdater

AtomicIntegerFieldUpdater为抽象类,提供基于反射的整型数值原子更新方法,借助AtomicIntegerFieldUpdater,可以实现对象中的整型属性进行原子更新操作。使用示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class EatChicken {
private static final AtomicIntegerFieldUpdater<Player> chickenUpdate = AtomicIntegerFieldUpdater.newUpdater(Player.class, "chicken");
public static void main(String[] args) throws Exception {
final Player player = new Player();
player.setName("DuckyRain");
for (int i = 0; i < 10; ++i) {
new Thread(() -> chickenUpdate.getAndAdd(player, 1)).start();
}
Thread.sleep(1000L);
System.out.println(player.getName() + ", eat chicken " + player.getChicken() + " times.");
}
}
class Player {
String name;
volatile int chicken;
public String getName() {return name;}
public void setName(String name) { this.name = name;}
public int getChicken() {return chicken;}
public void setChicken(int chicken) {this.chicken = chicken;}
}
Loading comments...